package com.hsj.demo;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.hsj.utiles.FileUtiles;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

import static cn.hutool.core.date.DatePattern.CHINESE_DATE_TIME_PATTERN;

@Slf4j
public class TestMain {
    /*
     * 输出目录
     * */
    //public static String OUT_PATH = "D:\\BaiduNetdiskDownload\\1\\myvideo\\";
    //执行成功0,失败1
    private static int CODE_SUCCESS = 0;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String inPath = null;
        String outPath = null;
        List<File> fileList = null;
        boolean b = true;
        while (true) {
            inPath = viaInPath(sc);
            outPath = viaOutPath(sc);
            fileList = FileUtiles.getMp4FileFind(inPath);
            videoFinger(fileList, outPath);
            System.exit(2);
        }
        //  String path = "D:\\BaiduNetdiskDownload\\1\\";
     /*   List<File> fileList = FileUtiles.getMp4FileFind(path);
        videoFinger(fileList);*/
       // test();
    }

    private static String viaInPath(Scanner sc) {
        System.out.println("请输入要去重的文件目录:例如:D:\\BaiduNetdiskDownload\\1\\myvideo\\");
        String inPath = sc.nextLine();
        if (StrUtil.isEmpty(inPath)) {
            System.err.println("你输入的目录不能为空");
            return viaInPath(sc);
        }
        File inFile = new File(inPath);
        if (!FileUtil.exist(inFile)) {
            System.err.println("要去重的文件目录不存在,请输入正确的目录");
            return viaInPath(sc);
        }
        System.err.println("要去重的文件目录为：" + inPath);
        return inPath;
    }

    private static String viaOutPath(Scanner sc) {
        System.out.println("请输入要输出的文件目录:例如:D:\\BaiduNetdiskDownload\\1\\");
        String outPath = sc.nextLine();
        if (StrUtil.isEmpty(outPath)) {
            System.err.println("你输出的目录不能为空");
            return viaInPath(sc);
        }
        File inFile = new File(outPath);
        if (!FileUtil.exist(inFile)) {
            System.err.println("要输出的文件目录不存在,请输入正确的目录");
            return viaInPath(sc);
        }
        System.err.println("要去重的文件目录为：" + outPath);
        List<File> fileList = FileUtiles.getMp4FileFind(outPath);
        if (CollUtil.isNotEmpty(fileList)) {
            System.err.println("该目录下有：" + fileList.size() + "个文件");
            System.err.println("请清空该目录下的所的文件，否则将会报错！,请确认是否删除!");
            System.err.println("确认删除请按1,否则将返回");
            int rscDel = sc.nextInt();
            if (rscDel == 1) {
                FileUtiles.deleteFile(fileList);
                return outPath + "\"\\";
            } else {
                return viaOutPath(sc);
            }
        }
        return outPath + "\"\\";
    }

    private static void videoFinger(List<File> fileList, String outPath) {
        if (CollUtil.isEmpty(fileList)) return;
        log.info("开始处理文件。。。。。。。。。。。。");
        long begLong = System.currentTimeMillis();
        for (File file : fileList) {
            log.info("处理文件:{}", file.getAbsolutePath());
            videoFinger(file, outPath);
            log.info("文件处理结束:{}", file.getAbsolutePath());
        }
        long endLong = System.currentTimeMillis();
        System.out.println("执行完成,总共耗时:" + (endLong - begLong) / 1000 + " 秒");
    }

    private static void videoFinger(File file,
                                    String outPath) {
        StringBuilder stb = new StringBuilder();
        stb.append(" -i ");
        stb.append(file.getAbsolutePath());
        //stb.append(" -vf mpdecimate,setpts=N/FRAME_RATE/TB -map 0:v ");
        stb.append(" -c:v libx264 -crf 18 -c:a copy ");
        stb.append(outPath + "out_")
                .append(DateUtil.format(new Date(), CHINESE_DATE_TIME_PATTERN))
                .append("_" + file.getName());
        System.out.println(stb.toString());
        System.out.println("开始执行去重命令");
        FfmpegCmdTest.cmdExecut(stb.toString());
        System.out.println("执行结束");
    }

    private static void test() {
        String inputVideoPath = "\u202AD:\\BaiduNetdiskDownload\\1\\1.mp4"; // 输入视频文件路径
        String outputVideoPath = "\u202AD:\\BaiduNetdiskDownload\\1\\1_out111.mp4"; // 去重后输出视频文件路径

        try {
            // 构建FFmpeg命令
            // 这里的-f lavfi表示使用libavfilter的虚拟设备，-i anullsrc表示无声音的原始源输入，
            // -t 5 -frame_pts 1输出5秒的视频，每帧的PTS设置为1，以便后续处理
            String ffmpegCommand = "ffmpeg -i " + inputVideoPath + " -f lavfi -i anullsrc -t 5 -frame_pts 1 -an -c:v libx264 -preset veryfast -f mp4 /dev/null";

            // 执行FFmpeg命令
            Process process = Runtime.getRuntime().exec(ffmpegCommand);

            // 等待FFmpeg命令执行完成
            process.waitFor();

            // 读取FFmpeg的输出，进行进一步处理（如果有必要）
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                // 处理FFmpeg的输出
            }
            reader.close();

            // 构建最终的去重命令
            // 使用-vf select='not(eq(pict_type\,I)-eq(n,1))+not(eq(pict_type\,P)-eq(n,1))'过滤掉非I帧和非B帧前的P帧
            String finalCommand = "ffmpeg -i - -vf \"select='not(eq(pict_type\\,I)-eq(n\\,1))+not(eq(pict_type\\,P)-eq(n\\,1))'\" -an -c:v libx264 -preset veryfast " + outputVideoPath;

            // 执行去重命令，输入从管道读取，输出到目标文件
            process = Runtime.getRuntime().exec(finalCommand, null, null);

            // 将FFmpeg的输出重定向到输出文件
            process.getOutputStream().close(); // 关闭输入流，因为我们不会写入任何数据
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while ((line = reader.readLine()) != null) {
                // 处理去重过程的输出
            }
            reader.close();

            // 等待去重过程完成
            process.waitFor();

            System.out.println("视频去重完成，输出文件路径: " + outputVideoPath);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

    }
}
